<template>
  <div class="fusion-card">
    <div class="form">
      <div class="model">
        <a-card size="small" class="card info" :bordered="false" :hoverable="true">
          <div class="title">数据模型信息：</div>
          <a-form ref="formRef" :model="form" :rules="rules" :label-col="{ style: { width: '120px' } }">
            <a-row>
              <a-col :span="24">
                <a-form-item label="数据模型代码" name="modelCode">
                  <a-input style="width: 100%" v-model:value="form.modelCode" placeholder="请输入数据模型代码" />
                </a-form-item>
              </a-col>
              <a-col :span="24">
                <a-form-item label="数据模型名称" name="modelName">
                  <a-input style="width: 100%" v-model:value="form.modelName" placeholder="请输入数据模型名称" />
                </a-form-item>
              </a-col>
              <a-col :span="24">
                <a-form-item label="订阅主题" name="subscribeTopic">
                  <a-input
                    style="width: 100%; background-color: #eee; color: #000"
                    v-model:value="form.subscribeTopic"
                    placeholder="请输入订阅主题"
                    disabled
                  />
                </a-form-item>
              </a-col>
              <a-col :span="24">
                <a-form-item label="频率(秒)" name="frequency">
                  <a-input style="width: 100%" v-model:value="form.frequency" placeholder="请输入频率（秒）" />
                </a-form-item>
              </a-col>
            </a-row>
          </a-form>
        </a-card>
        <a-card size="small" class="card attr" :bordered="false" :hoverable="true">
          <div class="title">融合字段表：</div>
          <div class="attr-table">
            <a-table :columns="attrcolumns" :data-source="tableData" :pagination="false">
              <template #bodyCell="{ record, column }">
                <template v-if="column.dataIndex === 'dataType'">
                  {{ getDictLabel(record.dataType, dataTypeDict) }}
                </template>
                <template v-if="column.dataIndex === 'action'">
                  <div class="smart-table-operate">
                    <a-button type="link" @click="onDelete(record)"> 删除</a-button>
                  </div>
                </template>
              </template>
            </a-table>
          </div>
        </a-card>
      </div>
      <div class="column">
        <a-card size="small" class="card" :bordered="false" :hoverable="true">
          <div class="attr-search">
            <div class="title">请选择融合的数据模型：</div>
            <a-select ref="select" v-model:value="modelId" placeholder="请选择数据类型" @change="modelChange" class="input">
              <a-select-option v-for="item in modelList" :key="item.modelId" :value="item.modelId">
                {{ item.modelName }}
              </a-select-option>
            </a-select>
          </div>
          <div class="attr-table">
            <a-table
              :columns="columns"
              :data-source="attrList"
              :pagination="false"
              rowKey="attrId"
              :customRow="customRow"
              :row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
            >
              <template #bodyCell="{ record, column }">
                <template v-if="column.dataIndex === 'dataType'">
                  {{ getDictLabel(record.dataType, dataTypeDict) }}
                </template>
              </template>
            </a-table>
          </div>
        </a-card>
      </div>
    </div>
    <div class="button-list">
      <a-button class="button-item" @click="onClose">重 置</a-button>
      <a-button class="button-item" type="primary" @click="onSubmit">保 存</a-button>
    </div>
  </div>
</template>
<script setup>
  import { ref, reactive, onMounted, onUnmounted, watch } from 'vue';
  import { message } from 'ant-design-vue';
  import { dataTypeDict } from '/@/assets/js/dict';
  import { getDictLabel } from '/@/utils/mixin';
  import { iotApi as iotModelApi } from '/@/api/plat/dataModel';
  import { iotApi as iotAttrApi } from '/@/api/plat/dataModelAttr';
  import { PageMixin } from '/@/utils/mixin';
  const { resetForm } = PageMixin();
  import { iotApi } from '/@/api/plat/dataModel';

  // 组件ref
  const formRef = ref();

  const formDefault = {
    modelCode: undefined,
    modelName: undefined,
    subscribeTopic: undefined,
    frequency: undefined,
    isEnable: 0,
    status: undefined,
    isFused: 1,
  };

  const columns = ref([
    {
      title: '属性字段编码',
      dataIndex: 'attrCode',
    },
    {
      title: '属性名称',
      dataIndex: 'attrName',
    },
    {
      title: '数据类型',
      dataIndex: 'dataType',
    },
  ]);

  const attrcolumns = ref(
    columns.value.concat([
      {
        title: '操作',
        dataIndex: 'action',
        fixed: 'right',
        width: 80,
      },
    ])
  );
  const modelList = ref([]);
  const tableData = ref([]);
  const attrList = ref([]);
  const modelId = ref(undefined);
  let subscribeTopic = undefined;
  // 选择表格行
  const selectedRowKeyList = ref([]);

  let form = reactive({ ...formDefault });

  const rules = {
    modelCode: [{ required: true, message: '请填写数据模型代码' }],
    modelName: [{ required: true, message: '请填写数据模型名称' }],
    subscribeTopic: [{ required: true, message: '请填写订阅主题' }],
    frequency: [{ required: true, message: '请填写频率' }],
  };

  function getModelList() {
    iotModelApi.queryList().then(({ data }) => {
      modelList.value = data;
    });
  }

  function modelChange(val) {
    iotAttrApi.queryList({ modelId: val }).then(({ data }) => {
      attrList.value = data;
    });
    const row = modelList.value.find((m) => m.modelId === val) || {};
    subscribeTopic = row.subscribeTopic;
  }

  // 每一行绑定点击事件
  const customRow = (record, index) => {
    return {
      onClick: () => {
        onSelectChange(null, [record]);
      },
    };
  };

  // 列选择
  function onSelectChange(selectedRowKeys, selectedRows) {
    if (selectedRows.length > 0) {
      const attrId = selectedRows[0].attrId;
      const index = tableData.value.findIndex((m) => m.attrId === attrId);
      if (index >= 0) {
        tableData.value.splice(index, 1);
        selectedRowKeyList.value.splice(index, 1);
      } else {
        const row = selectedRows[0];
        row.subscribeTopic = subscribeTopic;
        tableData.value.push(row);
        selectedRowKeyList.value.push(attrId);
      }
      form.subscribeTopic = [...new Set(tableData.value.map((item) => item.subscribeTopic))].join(',');
    }
  }

  function onDelete(row) {
    const index = tableData.value.findIndex((m) => m.attrId === row.attrId);
    tableData.value.splice(index, 1);
    selectedRowKeyList.value.splice(index, 1);
  }

  function onClose() {
    resetForm(form, formDefault);
    tableData.value = [];
    selectedRowKeyList.value = [];
  }

  async function onSubmit() {
    try {
      await formRef.value.validateFields();
      save(form);
    } catch (err) {
      message.error('参数验证错误，请仔细填写表单数据!');
    }
  }

  // 新建、编辑API
  async function save() {
    const list = tableData.value.map((m) => {
      const { attrId, ...obj } = m;
      return obj;
    });
    form.modelAttrs = list;
    iotApi.fullAdd(form).then(({ data }) => {
      if (!data) {
        message.error('保存失败，请检查参数是否正确!');
      } else {
        message.success('保存成功');
        onClose();
      }
    });
  }

  onMounted(getModelList);
</script>

<style scoped lang="less">
  .fusion-card {
    height: 100%;
    width: 100%;
    position: relative;
    .form {
      display: flex;
      height: calc(100% - 20px);
      justify-content: space-between;
      position: relative;
    }
    .model {
      width: 50%;
      height: 100%;
      display: flex;
      flex-direction: column;
      .info {
        height: 360px;
      }
      .attr {
        height: calc(100% - 360px - 20px - 60px);
        margin-top: 20px;
        .attr-table {
          height: calc(100% - 45px);
          overflow-y: scroll;
        }
      }
      .card {
        .title {
          height: 40px;
          font-size: 16px;
          font-weight: 700;
          margin-bottom: 15px;
          padding-bottom: 15px;
          padding-left: 10px;
          border-bottom: 1px solid #eee;
          position: relative;
          &::before {
            content: '';
            position: absolute;
            top: 6px;
            left: 0;
            width: 3px;
            height: 14px;
            background-color: #1677ff;
          }
        }
      }
    }
    .column {
      width: calc(50% - 20px);
      height: 100%;
      .card {
        height: 100%;
        .attr-search {
          display: flex;
          align-items: center;
          margin-bottom: 20px;
          .input {
            width: 200px;
          }
          .title {
            font-size: 16px;
            font-weight: 700;
            position: relative;
            padding-left: 10px;
            &::before {
              content: '';
              position: absolute;
              top: 6px;
              left: 0;
              width: 3px;
              height: 14px;
              background-color: #1677ff;
            }
          }
        }
        .attr-table {
          height: calc(100% - 45px);
          overflow-y: scroll;
        }
      }
    }
    .button-list {
      position: absolute;
      z-index: 99;
      bottom: 0px;
      left: -10px;
      height: 60px;
      background-color: #fff;
      width: calc(100% + 20px);
      border-top: 1px solid #eee;
      padding: 0 20px;
      display: flex;
      align-items: center;
      box-shadow: 0 -10px 10px #eee;
      .button-item {
        margin-right: 15px;
      }
    }
  }
  ::v-deep .ant-card-body {
    height: 100%;
  }
</style>
